#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../header/all.h"

void getln(char *buf, int nBufSize) {
    int pos = 0;
    // fgets 读取指定个数字符, 包括换行, 读到文件结尾为止
    // 若能装下, 则 buf 后面补 0, 若不能装下, 则不补 0
    if (fgets(buf, nBufSize, stdin) != NULL && buf[0] != '\n') {
        while (buf[pos] != '\n' && buf[pos] != 0) { ++pos; }
        if (buf[pos] == '\n') { buf[pos] = 0; }
        else { while (getchar() != '\n') {} }
    }
    else { buf[0] = 0; }
}

double getln2f() {
    char buf[100];
    double cast;
    getln(buf, 100);
    cast = atof(buf);
    if (cast == 0.0 && strcmp("0", buf) != 0) return -1;
    return cast;
}

void mystrcpy(char *dst, int nDstSize, const char *src, int nSrcSize) {
    int minsize = nDstSize < nSrcSize ? nDstSize : nSrcSize;
    memcpy(dst, src, minsize);
    dst[minsize - 1] = 0;
}

const char *center(const char *str, int width) {
    #define N_POINTER_SIZE 1000
    static char *bufs[N_POINTER_SIZE];
    static int nstr = 0;

    int len = strlen(str);
    if (width < 3) { return ""; }
    if (len == width) { return str; }

    if (nstr >= N_POINTER_SIZE) { nstr = 0; }
    free(bufs[nstr]);
    bufs[nstr] = malloc(width + 5);

    // 字符串长度小于宽度, 左右补空格
    if (len < width) {
        int leftWhite, rightWhite, npos = 0;
        leftWhite  = (width - len) >> 1;
        rightWhite =
            (leftWhite << 1) == (width - len) ?
            leftWhite : leftWhite + 1;

        for (int i = 0; i < leftWhite; ++i, ++npos) {
            bufs[nstr][npos] = ' ';
        }
        mystrcpy(bufs[nstr] + npos, width - npos, str, width - npos);
        npos += len;
        for (int i = 0; i < rightWhite; ++i, ++npos) {
            bufs[nstr][npos] = ' ';
        }
        bufs[nstr][npos] = 0;

    // 字符串长度大于宽度, 截断后加 "..." 或 "... ", 使得字符串宽度刚好为宽度
    } else {
        int npos = 0;
        while (npos + 4 < width) {
            if ((unsigned)str[npos] <= 0x7F) {
                bufs[nstr][npos] = str[npos];
                ++npos;
            }
            else {
                bufs[nstr][npos] = str[npos];
                ++npos;
                bufs[nstr][npos] = str[npos];
                ++npos;
            }
        }
        bufs[nstr][npos] = '.';
        bufs[nstr][++npos] = '.';
        bufs[nstr][++npos] = '.';
        ++npos;
        if (npos != width) {
            bufs[nstr][npos] = ' ';
        }
        bufs[nstr][++npos] = 0;
    }

    return bufs[nstr++];
    #undef N_POINTER_SIZE
}
